using build

class Build: BuildPod {

	override Void setup() {
		// TODO See math/build.fan for some comments on these.
		podName = "testMath"
		version = Version("0.1")
	}

	@target = "run tests on math"
	override Void test() {
		// Redone to avoid new JVM spawns. Too slow that way.
		startTime := DateTime.now
		failureCount := 0
		failureNames := Str[,]
		methodCount := 0
		verifyCount := 0
		echo("")
		testTypes := Pod.find(podName).types.findAll{it.fits(Test#)}
		testTypes.each |type| {
			methods := type.methods.findAll{it.name.startsWith("test") && !it.isAbstract}
			methodCount += methods.size
			methods.each |method| {
				testName := "${type.qname}.${method.name}"
				try {
					echo("-- Run: $testName ...")
					Test? test
					try {
						test = type.make
					} catch (Err err) {
						echo("")
						echo("ERROR: Cannot make test $type")
						err.trace
						throw FailureErr()
					}
					try {
						test.setup
						method.call(test)
					} catch (Err err) {
						echo("")
						echo("TEST FAILED")
						err.trace
						throw FailureErr()
					} finally {
						try {
							test.teardown
						} catch (Err err) {
							err.trace
						}
					}
					verifyCount += test->verifyCount
					echo("   Pass: ${testName} [${test->verifyCount}]")
				} catch (FailureErr err) {
					failureCount++
					failureNames.add(testName)
				}
			}
		}
		echo("")
		echo("Time: ${DateTime.now - startTime}")
		echo("")
		if (!failureNames.isEmpty) {
			echo("Failed:")
			failureNames.each {
				echo("  $it")
			}
			echo("")
		}
		echo("***")
		echo("*** ${failureCount == 0 ? "All tests passed!" : failureCount + " FAILURES"} [${testTypes.size} tests, $methodCount methods, $verifyCount verifies]")
		echo("***")
	}

}

const class FailureErr: Err {
	// TODO This is sort of annoying, but I guess the super allows optional args.
	// TODO One down side to not using overloading?
	// TODO Or allow leaving out the optionals automatically?
	new make(): super() {}
}
